#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <thread>
#include <chrono>

void test_tlv_client(int tag, const std::string &value)
{
    std::cout << "📤 发送请求: tag=" << tag << ", value='" << value << "'" << std::endl;

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        std::cerr << "❌ 创建socket失败" << std::endl;
        return;
    }

    // 设置连接超时
    struct timeval timeout;
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
    setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));

    sockaddr_in server_addr{};
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8888);
    inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);

    if (connect(sockfd, (sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        std::cerr << "❌ 连接服务器失败" << std::endl;
        close(sockfd);
        return;
    }

    // 构建TLV数据
    int length = value.size();
    std::string tlv_data;
    tlv_data.append(reinterpret_cast<const char *>(&tag), sizeof(tag));
    tlv_data.append(reinterpret_cast<const char *>(&length), sizeof(length));
    tlv_data.append(value);

    // 发送数据
    ssize_t sent = send(sockfd, tlv_data.c_str(), tlv_data.size(), 0);
    if (sent < 0)
    {
        std::cerr << "❌ 发送数据失败" << std::endl;
        close(sockfd);
        return;
    }

    std::cout << "✅ 发送成功: " << sent << " 字节" << std::endl;

    // 等待服务器处理并接收响应
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    // 接收响应
    char buffer[4096];
    ssize_t received = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
    if (received > 0)
    {
        buffer[received] = '\0';
        std::cout << "📥 收到响应 (" << received << " 字节): " << std::endl;
        std::cout << "   " << buffer << std::endl;
    }
    else if (received == 0)
    {
        std::cout << "⚠️  连接已关闭" << std::endl;
    }
    else
    {
        std::cout << "❌ 接收响应失败" << std::endl;
    }

    // 关闭连接
    close(sockfd);
    std::cout << "----------------------------------------" << std::endl;
}

int main()
{
    std::cout << "🚀 搜索引擎服务器功能测试" << std::endl;
    std::cout << "========================================" << std::endl;

    // 等待服务器启动
    std::cout << "⏳ 等待服务器启动..." << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(2));

    // 测试关键字推荐
    std::cout << "\n🔍 测试关键字推荐功能 (tag=1):" << std::endl;
    std::cout << "----------------------------------------" << std::endl;

    test_tlv_client(1, "hello");
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    test_tlv_client(1, "中国");
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    test_tlv_client(1, "科技");
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    test_tlv_client(1, "人工智能");
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    // 测试网页搜索
    std::cout << "\n🌐 测试网页搜索功能 (tag=2):" << std::endl;
    std::cout << "----------------------------------------" << std::endl;

    test_tlv_client(2, "hello world");
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    test_tlv_client(2, "机器学习");
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    test_tlv_client(2, "大数据技术");
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    test_tlv_client(2, "深度学习应用");
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    // 测试错误类型
    std::cout << "\n⚠️  测试错误类型 (tag=3):" << std::endl;
    std::cout << "----------------------------------------" << std::endl;

    test_tlv_client(3, "unknown type");
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    // 测试空数据
    std::cout << "\n🔍 测试边界情况:" << std::endl;
    std::cout << "----------------------------------------" << std::endl;

    test_tlv_client(1, ""); // 空关键词
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    std::cout << "\n🎉 所有测试请求已发送!" << std::endl;
    std::cout << "💡 查看服务器终端可以看到详细处理日志" << std::endl;

    return 0;
}